/**
 * Copyright 2009 Adam Ruggles.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.google.code.sapien.security;

import java.io.Serializable;

import javax.persistence.Embeddable;

import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;

/**
 * A Collection of permissions associated with a role.
 * @author Adam
 * @version $Id$
 * 
 * Created on May 16, 2009 at 9:13:44 AM 
 */
@Embeddable
public class RolePermissions extends AbstractPermissions implements Serializable {
	/**
	 * Add category constant value.
	 */
	public static final int ADD_CATEGORY = 1 << 1;

	/**
	 * Add role constant value.
	 */
	public static final int ADD_ROLE = 1 << 2;

	/**
	 * Access to the administrator areas constant value.
	 */
	public static final int ADMIN_ACCESS = 1 << 3;

	/**
	 * Edit category constant value.
	 */
	public static final int EDIT_CATEGORY = 1 << 4;

	/**
	 * Edit role constant value.
	 */
	public static final int EDIT_ROLE = 1 << 5;

	/**
	 * Serial Version UID.
	 */
	private static final long serialVersionUID = -5886494170687455794L;

	/**
	 * Default constructor.
	 */
	public RolePermissions() {
		super();
	}

	/**
	 * Constructs a RolePemissions with a value.
	 * @param value The value to set.
	 */
	public RolePermissions(final int value) {
		super(value);
	}

	/**
	 * Constructs a RolePermissions with an array of role permission values.
	 * @param permissions An array of role permission values.
	 */
	public RolePermissions(final int[] permissions) {
		super();
		for (int permission : permissions) {
			add(permission);
		}
	}

	/**
	 * Constructs a new RolePemissions with the same permissions.
	 * @param permissions A RolePermissions to initialize to.
	 */
	public RolePermissions(final RolePermissions permissions) {
		super(permissions.getValue());
	}

	/**
	 * {@inheritDoc}
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(final Object obj) {
		if (this == obj) {
			return true;
		}
		if (!(obj instanceof RolePermissions)) {
			return false;
		}
		final RolePermissions rhs = (RolePermissions) obj;
		return new EqualsBuilder()
			.append(getValue(), rhs.getValue())
			.isEquals();
	}

	/**
	 * {@inheritDoc}
	 * @see java.lang.Object#hashCode()
	 */
	@Override
	public int hashCode() {
		return new HashCodeBuilder(97, 3)
			.append(getValue())
			.toHashCode();
	}

	/**
	 * Returns true if the add category permission is set to true.
	 * @return true if the add category permission is set to true.
	 */
	public boolean isCanAddCategory() {
		return isValueSet(ADD_CATEGORY);
	}

	/**
	 * Returns true if the add role permission is set to true.
	 * @return true if the add role permission is set to true.
	 */
	public boolean isCanAddRole() {
		return isValueSet(ADD_ROLE);
	}

	/**
	 * Returns true if the admin access permission is set to true.
	 * @return true if the admin access permission is set to true.
	 */
	public boolean isCanAdminAccess() {
		return isValueSet(ADMIN_ACCESS);
	}

	/**
	 * Returns true if the edit category permission is set to true.
	 * @return true if the edit category permission is set to true.
	 */
	public boolean isCanEditCategory() {
		return isValueSet(EDIT_CATEGORY);
	}

	/**
	 * Returns true if the edit role permission is set to true.
	 * @return true if the edit role permission is set to true.
	 */
	public boolean isCanEditRole() {
		return isValueSet(EDIT_ROLE);
	}

	/**
	 * Sets canAddCategory.
	 * @param canAddCategory the canAddCategory to set.
	 */
	public void setCanAddCategory(final boolean canAddCategory) {
		if (canAddCategory) {
			add(ADD_CATEGORY);
		} else {
			remove(ADD_CATEGORY);
		}
	}

	/**
	 * Sets canAddRole.
	 * @param canAddRole the canAddRole to set.
	 */
	public void setCanAddRole(final boolean canAddRole) {
		if (canAddRole) {
			add(ADD_ROLE);
		} else {
			remove(ADD_ROLE);
		}
	}

	/**
	 * Sets canAdminAccess.
	 * @param canAdminAccess the canAdminAccess to set.
	 */
	public void setCanAdminAccess(final boolean canAdminAccess) {
		if (canAdminAccess) {
			add(ADMIN_ACCESS);
		} else {
			remove(ADMIN_ACCESS);
		}
	}

	/**
	 * Sets canEditCategory.
	 * @param canEditCategory the canEditCategory to set.
	 */
	public void setCanEditCategory(final boolean canEditCategory) {
		if (canEditCategory) {
			add(EDIT_CATEGORY);
		} else {
			remove(EDIT_CATEGORY);
		}
	}

	/**
	 * Sets canEditRole.
	 * @param canEditRole the canEditRole to set.
	 */
	public void setCanEditRole(final boolean canEditRole) {
		if (canEditRole) {
			add(EDIT_ROLE);
		} else {
			remove(EDIT_ROLE);
		}
	}

	/**
	 * {@inheritDoc}
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return new ToStringBuilder(this)
			.append("canAddCategory", isCanAddCategory())
			.append("canAddRole", isCanAddRole())
			.append("canEditCategory", isCanEditCategory())
			.append("canEditRole", isCanEditRole())
			.append("canAdminAccess", isCanAdminAccess())
			.toString();
	}
}
